home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_3 / multiuser / src / library / segment.c < prev    next >
C/C++ Source or Header  |  1994-06-29  |  8KB  |  304 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Segment Management                                                        *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993-1994 Geert Uytterhoeven                        *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <exec/execbase.h>
  12. #include <exec/alerts.h>
  13. #include <dos/dos.h>
  14. #include <dos/dosextens.h>
  15. #include <dos/dostags.h>
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18. #include <proto/utility.h>
  19.  
  20. #include "Memory.h"
  21. #include "Segment.h"
  22. #include "Misc.h"
  23. #include "Config.h"
  24. #include "Locale.h"
  25. #include "LibHeader.h"
  26. #include "Task.h"
  27.  
  28.  
  29.     /*
  30.      *        Static Routines
  31.      */
  32.  
  33. static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner);
  34. static void RemSegNode(struct muSegNode *snode);
  35. static struct muSegNode *FindSegNode(BPTR SegList);
  36. static struct muExtOwner *GetSegOwner(BPTR seglist);
  37.  
  38.  
  39.     /*
  40.      *        Allocate and Add a Segment Node
  41.      *
  42.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  43.      */
  44.  
  45. static struct muSegNode *AddSegNode(BPTR seglist, ULONG owner)
  46. {
  47.     struct muSegNode *snode;
  48.  
  49.     if (snode = MAlloc(sizeof(struct muSegNode))) {
  50.         snode->SegList = seglist;
  51.         snode->Owner.uid = (owner & muMASK_UID)>>16;
  52.         snode->Owner.gid = owner & muMASK_GID;
  53.         AddHead((struct List *)&muBase->SegOwnerList, (struct Node *)&snode->Node);
  54.     }
  55.     return(snode);
  56. }
  57.  
  58.  
  59.     /*
  60.      *        Remove and Deallocate a Segment Node
  61.      *
  62.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  63.      */
  64.  
  65. static void __inline RemSegNode(struct muSegNode *snode)
  66. {
  67.     Remove((struct Node *)&snode->Node);
  68.     Free(snode, sizeof(struct muSegNode));
  69. }
  70.  
  71.  
  72.     /*
  73.      *        Find the Segment Node for a given SegList
  74.      *
  75.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  76.      */
  77.  
  78. static struct muSegNode *FindSegNode(BPTR seglist)
  79. {
  80.     struct MinNode *node;
  81.     struct muSegNode *snode;
  82.  
  83.     for (node = muBase->SegOwnerList.mlh_Head;
  84.           node->mln_Succ && ((snode = (struct muSegNode *)node)->SegList != seglist);
  85.           node = node->mln_Succ);
  86.     if (!node->mln_Succ)
  87.         snode = NULL;
  88.     return(snode);
  89. }
  90.  
  91.  
  92.     /*
  93.      *        Get the owner of a Segment
  94.      *
  95.      *        Make sure you have access to the list (via ObtainSemaphore(Shared))!!
  96.      */
  97.  
  98. static struct muExtOwner *GetSegOwner(BPTR seglist)
  99. {
  100.     struct muExtOwner *owner = NULL;
  101.     struct muSegNode *snode;
  102.  
  103.     ObtainSemaphoreShared(&muBase->SegOwnerSem);
  104.     if (snode = FindSegNode(seglist))
  105.         owner = &snode->Owner;
  106.     ReleaseSemaphore(&muBase->SegOwnerSem);
  107.     return(owner);
  108. }
  109.  
  110.  
  111.     /*
  112.      *        Init Segment List
  113.      */
  114.  
  115. void InitSegList(void)
  116. {
  117.     ObtainSemaphore(&muBase->SegOwnerSem);
  118.     NewList((struct List *)&muBase->SegOwnerList);
  119.     ReleaseSemaphore(&muBase->SegOwnerSem);
  120. }
  121.  
  122.  
  123.     /*
  124.      *        Replacement for the dos.library LoadSeg() function
  125.      */
  126.  
  127. BPTR __asm __saveds NEWLoadSeg(register __d1 STRPTR name, register __a6 struct DosLibrary *dosbase)
  128. {
  129.     BPTR fl;
  130.     struct FileInfoBlock *fib;
  131.     ULONG owner = muOWNER_NOBODY;
  132.     BPTR seglist;
  133.  
  134.     if (name && (fl = Lock(name, ACCESS_READ))) {
  135.         if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
  136.              (fib = AllocDosObject(DOS_FIB, NULL))) {
  137.             if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
  138.                 owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
  139.             FreeDosObject(DOS_FIB, fib);
  140.         }
  141.         UnLock(fl);
  142.     }
  143.     seglist = muBase->OLDLoadSeg(name, dosbase);
  144.     if (owner & muMASK_UID) {
  145.         ObtainSemaphore(&muBase->SegOwnerSem);
  146.         AddSegNode(seglist, owner);
  147.         ReleaseSemaphore(&muBase->SegOwnerSem);
  148.     }
  149.     return(seglist);
  150. }
  151.  
  152.  
  153.     /*
  154.      *        Replacement for the dos.library NewLoadSeg() function
  155.      */
  156.  
  157. BPTR __asm __saveds NEWNewLoadSeg(register __d1 STRPTR name, register __d2 struct TagItem *tags,
  158.                                              register __a6 struct DosLibrary *dosbase)
  159. {
  160.     BPTR fl;
  161.     struct FileInfoBlock *fib;
  162.     ULONG owner = muOWNER_NOBODY;
  163.     BPTR seglist;
  164.  
  165.     if (name && (fl = Lock(name, ACCESS_READ))) {
  166.         if (CheckmuFSVolume(((struct FileLock *)BADDR(fl))->fl_Task) &&
  167.              (fib = AllocDosObject(DOS_FIB, NULL))) {
  168.             if (Examine(fl, fib) && (fib->fib_Protection & muFIBF_SET_UID))
  169.                 owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
  170.             FreeDosObject(DOS_FIB, fib);
  171.         }
  172.         UnLock(fl);
  173.     }
  174.     seglist = muBase->OLDNewLoadSeg(name, tags, dosbase);
  175.     if (owner & muMASK_UID) {
  176.         ObtainSemaphore(&muBase->SegOwnerSem);
  177.         AddSegNode(seglist, owner);
  178.         ReleaseSemaphore(&muBase->SegOwnerSem);
  179.     }
  180.     return(seglist);
  181. }
  182.  
  183.  
  184.     /*
  185.      *        Replacement for the dos.library UnLoadSeg() function
  186.      */
  187.  
  188. BOOL __asm __saveds NEWUnLoadSeg(register __d1 BPTR seglist, register __a6 struct DosLibrary *dosbase)
  189. {
  190.     struct muSegNode *snode;
  191.  
  192.     ObtainSemaphoreShared(&muBase->SegOwnerSem);
  193.     if (snode = FindSegNode(seglist))
  194.         RemSegNode(snode);
  195.     ReleaseSemaphore(&muBase->SegOwnerSem);
  196.     return(muBase->OLDUnLoadSeg(seglist, dosbase));
  197. }
  198.  
  199.  
  200.     /*
  201.      *        Replacement for the dos.library InternalLoadSeg() function
  202.      */
  203.  
  204. BPTR __asm __saveds NEWInternalLoadSeg(register __d0 BPTR fh, register __a0 BPTR table,
  205.                                                     register __a1 LONG *functionarray, register __a2 LONG *stack,
  206.                                                     register __a6 struct DosLibrary *dosbase)
  207. {
  208.     struct FileInfoBlock *fib;
  209.     ULONG owner = muOWNER_NOBODY;
  210.     BPTR seglist;
  211.  
  212.     if (fh && CheckmuFSVolume(((struct FileHandle *)BADDR(fh))->fh_Type) &&
  213.          (fib = AllocDosObject(DOS_FIB, NULL))) {
  214.         if (ExamineFH(fh, fib) && (fib->fib_Protection & muFIBF_SET_UID))
  215.             owner = (fib->fib_OwnerUID<<16) | fib->fib_OwnerGID;
  216.         FreeDosObject(DOS_FIB, fib);
  217.     }
  218.     seglist = muBase->OLDInternalLoadSeg(fh, table, functionarray, stack, dosbase);
  219.     if (owner & muMASK_UID) {
  220.         ObtainSemaphore(&muBase->SegOwnerSem);
  221.         AddSegNode(seglist, owner);
  222.         ReleaseSemaphore(&muBase->SegOwnerSem);
  223.     }
  224.     return(seglist);
  225. }
  226.  
  227.  
  228.     /*
  229.      *        Replacement for the dos.library InternalUnLoadSeg() function
  230.      */
  231.  
  232. BOOL __asm __saveds NEWInternalUnLoadSeg(register __d1 BPTR seglist, register __a1 void (*freefunc)(),
  233.                                                       register __a6 struct DosLibrary *dosbase)
  234. {
  235.     struct muSegNode *snode;
  236.  
  237.     ObtainSemaphoreShared(&muBase->SegOwnerSem);
  238.     if (snode = FindSegNode(seglist))
  239.         RemSegNode(snode);
  240.     ReleaseSemaphore(&muBase->SegOwnerSem);
  241.  
  242.     return(muBase->OLDInternalUnLoadSeg(seglist, freefunc, dosbase));
  243. }
  244.  
  245.  
  246.     /*
  247.      *        Replacement for the dos.library CreateProc() function
  248.      */
  249.  
  250. struct Process __asm __saveds *NEWCreateProc(register __d1 STRPTR name, register __d2 LONG pri,
  251.                                                             register __d3 BPTR seglist, register __d4 LONG stacksize,
  252.                                                             register __a6 struct DosLibrary *dosbase)
  253. {
  254.     struct muExtOwner *owner;
  255.     struct Process *proc;
  256.  
  257.     if (owner = GetSegOwner(seglist))
  258.         PushTask(SysBase->ThisTask, owner);
  259.     proc = muBase->OLDCreateProc(name, pri, seglist, stacksize, dosbase);
  260.     if (owner)
  261.         PopTask(SysBase->ThisTask);
  262.     return(proc);
  263. }
  264.  
  265.  
  266.     /*
  267.      *        Replacement for the dos.library CreateNewProc() function
  268.      */
  269.  
  270. struct Process __asm __saveds *NEWCreateNewProc(register __d1 struct TagItem *tags,
  271.                                                                 register __a6 struct DosLibrary *dosbase)
  272. {
  273.     struct muExtOwner *owner = NULL;
  274.     struct Process *proc;
  275.     BPTR seglist;
  276.  
  277.     if (tags && (seglist = (BPTR)GetTagData(NP_Seglist, NULL, tags)) && (owner = GetSegOwner(seglist)))
  278.         PushTask(SysBase->ThisTask, owner);
  279.     proc = muBase->OLDCreateNewProc(tags, dosbase);
  280.     if (owner)
  281.         PopTask(SysBase->ThisTask);
  282.     return(proc);
  283. }
  284.  
  285.  
  286.     /*
  287.      *        Replacement for the dos.library RunCommand() function
  288.      */
  289.  
  290. LONG __asm __saveds NEWRunCommand(register __d1 BPTR seglist, register __d2 ULONG stacksize,
  291.                                              register __d3 STRPTR argptr, register __d4 ULONG argsize,
  292.                                              register __a6 struct DosLibrary *dosbase)
  293. {
  294.     struct muExtOwner *owner;
  295.     LONG rc;
  296.  
  297.     if (owner = GetSegOwner(seglist))
  298.         PushTask(SysBase->ThisTask, owner);
  299.     rc = muBase->OLDRunCommand(seglist, stacksize, argptr, argsize, dosbase);
  300.     if (owner)
  301.         PopTask(SysBase->ThisTask);
  302.     return(rc);
  303. }
  304.